package com.kylin.core.user.event.listener;

import com.kylin.core.user.event.repository.AddressDataHandler;
import com.kylin.core.user.query.handler.AddressTranslator;
import com.kylin.dal.entity.user.UserAddressEntry;
import com.kylin.domain.user.command.*;
import com.kylin.domain.user.vo.UserAddressVO;
import com.kylin.shared.common.PageResults;
import com.kylin.shared.enums.ResultCodeEnum;
import com.kylin.shared.exception.SystemException;
import com.querydsl.core.QueryResults;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.queryhandling.QueryHandler;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Objects;

/**
 * @author Damon S.
 * @version v1.0.1
 * @date 2020年12月30日 19:28
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AddressCommandHandler {

    private final AddressDataHandler handler;
    private final AddressTranslator translator;

    @CommandHandler
    @Transactional(rollbackFor = Exception.class)
    public Long createAddress(CreateUserAddressCommand command) {
        UserAddressEntry entry = handler.checkUserAddress(command);
        if (Objects.nonNull(entry)) {
            return entry.getId();
        }
        entry = handler.addUserAddress(command);
        Assert.notNull(entry, "创建用户收货地址失败。");
        return entry.getId();
    }

    @QueryHandler
    public UserAddressVO findDefaultOne(FindDefaultAddressCommand command) {
        UserAddressEntry entry = handler.findUserAddressDefault(command.getUserId());
        if (Objects.isNull(entry)) {
            return UserAddressVO.EMPTY;
        }
        return translator.toUserAddressVO(entry);
    }

    @CommandHandler
    @Transactional(rollbackFor = Exception.class)
    public boolean removeAddress(RemoveUserAddressCommand command) {
        return handler.removeUserAddress(command);
    }

    @QueryHandler
    private PageResults findAddress(QueryUserAddressCommand command) {
        QueryResults<UserAddressEntry> results = handler.findUserAddress(command);
        return PageResults.builder()
                .index(results.getOffset())
                .limit(results.getLimit())
                .total(results.getTotal())
                .results(results.getResults())
                .build();
    }

    @CommandHandler
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAddress(UpdateUserAddressCommand command) {
        return handler.updateUserAddress(command);
    }

    @CommandHandler
    @Transactional(rollbackFor = Exception.class)
    public Boolean setDefaultAddress(DefaultUserAddressCommand command) {
        if (!handler.setDefaultAddress(command)) {
            throw new SystemException(ResultCodeEnum.INTERNAL_ERROR.getMessage());
        }
        return Boolean.TRUE;
    }
}
